/*!
    \file    main.c
    \brief   使用systick实现LED闪烁，USART打印和按键示例

    \version 2025-05-30, V0.1.1, 适用于gd32c2x1的固件
*/

/*
    版权所有 (c) 2025, GigaDevice Semiconductor Inc.

    允许以源代码和二进制形式重新分发和使用，无论是否经过修改，
    但需满足以下条件：

    1. 源代码的再分发必须保留上述版权声明、本条件列表和以下免责声明。
    2. 二进制形式的再分发必须在随发行版提供的文档和/或其他材料中
       保留上述版权声明、本条件列表和以下免责声明。
    3. 未经特定事先书面许可，不得使用版权所有者或其贡献者的名称
       来支持或推广源自本软件的产品。

    本软件由版权所有者和贡献者按“原样”提供，不提供任何明示或
    暗示的担保，包括但不限于对适销性和特定用途适用性的暗示担保。
    在任何情况下，版权所有者或贡献者均不对因使用本软件而引起的
    任何直接、间接、偶然、特殊、示范性或后果性损害（包括但不限于
    采购替代商品或服务；使用、数据或利润损失；业务中断）承担责任，
    无论是在合同诉讼、严格责任或侵权（包括疏忽或其他原因）中产生的，
    即使已被告知可能发生此类损害。
*/

#include "gd32c2x1.h"
#include "systick.h"
#include "main.h"
#include "gd32c231c_eval.h"

/*!
    \brief      每500ms切换一次LED状态
    \param[in]  none
    \param[out] none
    \retval     none
    \note       该函数需周期性调用，实现LED1的闪烁效果
*/
void led_spark(void)
{
    static __IO uint32_t timingdelaylocal = 0U; // 静态变量，记录延时计数

    if(timingdelaylocal) {
        // timingdelaylocal非零时，判断当前计数值决定LED1状态
        if(timingdelaylocal < 500U) {
            gd_eval_led_on(LED1); // 前500ms点亮LED1
        } else {
            gd_eval_led_off(LED1); // 后500ms熄灭LED1
        }
        timingdelaylocal--; // 计数递减
    } else {
        timingdelaylocal = 1000U; // 重新装载计数，实现周期性
    }
}

/*!
    \brief      主函数入口
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
#ifdef __FIRMWARE_VERSION_DEFINE
    uint32_t fw_ver = 0; // 固件版本号变量
#endif
    /* 配置systick定时器，用于延时等功能 */
    systick_config();

    /* 初始化LED1和LED2 */
    gd_eval_led_init(LED1);
    gd_eval_led_init(LED2);

    /* 初始化串口，用于调试信息输出 */
    gd_eval_com_init(EVAL_COM);

    /* 初始化唤醒按键，设置为GPIO模式 */
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);

#ifdef __FIRMWARE_VERSION_DEFINE
    fw_ver = gd32c2x1_firmware_version_get(); // 获取固件版本号
    /* 打印固件版本号 */
    printf("\r\nGD32C2X1系列固件版本: V%d.%d.%d", (uint8_t)(fw_ver >> 24), (uint8_t)(fw_ver >> 16), (uint8_t)(fw_ver >> 8));
#endif /* __FIRMWARE_VERSION_DEFINE */

    /* 打印系统、AHB、APB总线时钟频率 */
    printf("\r\nCK_SYS 时钟频率为 %d", rcu_clock_freq_get(CK_SYS));
    printf("\r\nCK_AHB 时钟频率为 %d", rcu_clock_freq_get(CK_AHB));
    printf("\r\nCK_APB 时钟频率为 %d", rcu_clock_freq_get(CK_APB));

    while(1) {
        // 检测唤醒按键是否被按下（低电平有效）
        if(RESET == gd_eval_key_state_get(KEY_WAKEUP)) {
            delay_1ms(50); // 消抖延时50ms
            // 再次检测，确认按键确实被按下
            if(RESET == gd_eval_key_state_get(KEY_WAKEUP)) {
                gd_eval_led_toggle(LED2); // 切换LED2状态
            }
            // 等待按键释放，避免重复触发
            while(RESET == gd_eval_key_state_get(KEY_WAKEUP)) {
            }
        }
    }
}
